package jc223504;
/**
 * @(#)KookWai_A1.java
 *
 * KookWai_A1 application
 *
 * @Lock Kook Wai
 * @version 1.00 2011/3/24
 */

import java.util.ArrayList;

public class MainUI {

    ProjModel pm;
    GridView gv;
    GetUserInput gu;
	Car car = new Car();
	/**
     * Declare arrayList for cars
     */
    ArrayList<Car> CarArray = new ArrayList<Car>();


/**
* Call Project Model, Grid View and GetUser Input class
*/

    public MainUI()
    {
        pm = new ProjModel();
        gv = new GridView(this.pm); //pass in project model
        gu = new GetUserInput();


    }

/**
* Display menu
*/

    public void showMenu()
    {
        /*
        === MENU ===
        1. Set Number of horizontal lanes (H-street) [min 1, max 3]
        2. Set Number of vertical lanes  (V-street) [min 1, max 4]
        3. Set Probability of a car entering H-street [min 0, max 1]
        3. Set Probability of a car entering V-street [min 0, max 1]
        5. Run one simulation cycle
        6. Set and run number of simulation cycles [min 1, max 10]
        Enter your choice>           */


       while(true)
       {

        //gv.initGrid();
        //gv.showGrid(); //Grid show before menu

        System.out.print( " === MENU ===\n" +
                " 1. Set Number of horizontal lanes (H-street) [min 1, max 3]\n" +
                " 2. Set Number of vertical lanes  (V-street) [min 1, max 4]\n" +
                " 3. Set Probability of a car entering H-street [min 0, max 1]\n" +
                " 4. Set Probability of a car entering V-street [min 0, max 1]\n" +
                " 5. Run one simulation cycle\n" +
                " 6. Set and run number of simulation cycles [min 1, max 10]\n" +
                " ");

        String userChoice = GetUserInput.getUserChoice("Enter your choice>");
        int userChoiceInt = Integer.parseInt(userChoice);
        System.out.println("After int conversion" + userChoiceInt);

        switch(userChoiceInt)
        {
            case 1 : System.out.println("Menu 1");
                     setNumHorLanes();
                break;
            case 2 : System.out.println("Menu 2");
                     setNumVerLanes();
                break;
            case 3 : System.out.println("Menu 3");
            		setHorProb();
                break;
            case 4 : System.out.println("Menu 4");
            		setVerProb();
                break;
            case 5 : System.out.println("Menu 5");
            		setOneSimCycle();
                break;
            case 6 : System.out.println("Menu 6");
            		setMultiCycle();
                break;
            default : System.out.println("Error in entering menu choice");
                break;
        }
       }

      }

      /**
     * Set the number of horizontal lanes
     */

    public void setNumHorLanes ()
    {
        String userChoice = GetUserInput.getUserChoice("Enter number of horizontal lanes : ");
        int userChoiceInt = Integer.parseInt(userChoice);
        int lowerLimit = 1;
        int upperLimit = 3;
        if (userChoiceInt > upperLimit || userChoiceInt < lowerLimit)
        {
           System.out.println("Error in entering horizontal lanes");
           System.out.println("Please enter number above 1 and below 3. ");
           showMenu();
        } else { //if user enter the correct input
            pm.setHorLanes(userChoiceInt);
            //let user set the number
        }

    }

    /**
     * Set the number of vertical lanes
     */

    public void setNumVerLanes ()
    {
        String userChoice = GetUserInput.getUserChoice("Enter number of vertical lanes : ");
        int userChoiceInt = Integer.parseInt(userChoice);
        int lowerLimit = 1;
        int upperLimit = 4;
        if (userChoiceInt > upperLimit || userChoiceInt < lowerLimit)
        {
           System.out.println("Error in entering vertical lane");
           System.out.println("Please enter number above 1 and below 3. ");
           showMenu();
        } else { //if user enter the correct input
            pm.setVerLanes(userChoiceInt);
            //let user set the number
        }

    }

    public int showHorLanes()
    {
        return pm.getHorLanes();
    }

    public int showVerLanes()
    {
        return pm.getVerLanes();
    }

    /**
     * Setup one simulation cycle
     *
     * Note: Same layout with Multi simulation cycles
     */


    public void setOneSimCycle()
    {
    	gv.initGrid();
    	gv.buildHorLane(pm.getHorLanes());
    	gv.buildVerLane(pm.getVerLanes());

		/**
     	* Place trafic lights
     	*/
    	int trafficHorXPos = gv.setTrafficLightXPos(pm.getMiddleHor(),pm.getHorLanes());
    	int trafficHorYPos = gv.setTrafficLightYPos(pm.getMiddleVer(),pm.getVerLanes());
    	gv.buildTrafficLights(trafficHorXPos,trafficHorYPos, pm.getLightHor());

    	int trafficVerXPos = gv.setTrafficLightXPos(pm.getMiddleHor(),pm.getHorLanes());
		int trafficVerYPos = pm.getMiddleVer()-1;
		gv.buildTrafficLights(trafficVerXPos,trafficVerYPos, pm.getLightVer());

		/**
     	* Place cars
     	*/
    	for(int i=0; i < car.GenerateCarRandNum(); i++)
    	{
    		CarArray.add(new Car());
    	}
    	for(int i =0; i < CarArray.size(); i++)
    	{
    	  int j=i;
    	  if(j==0)
    	  {
    	  	CarArray.get(i).setYPos(car.GenerateRandCarXPos(pm.getGridSize()));
    	  	CarArray.get(i).setXPos(car.GenerateRandCarYPos(pm.getHorLanes(),pm.getMiddleHor()));
    	  }
    	  else if (j==1)
    	  {
    	  	CarArray.get(i).setXPos(car.GenerateRandCarXPos(pm.getGridSize()));
    	  	CarArray.get(i).setYPos(car.GenerateRandCarYPos(pm.getVerLanes(),pm.getMiddleVer()));

    	  }
    	}
    	for (int i = 0; i< CarArray.size(); i++)
    	{
    		gv.buildCars(CarArray.get(i).getXPos(),CarArray.get(i).getYPos());
    	}

    	gv.showGrid();
    	//break;

    }

    /**
     * Setup multi cycle simulation
     */

    public void setMultiCycle()
    {
    	String userChoice = GetUserInput.getUserChoice("Set the number of simulation cycles");
        int simCycles = Integer.parseInt(userChoice);
    	if(simCycles >=1 && simCycles <=10)
    	{
    		int gs = pm.getGridSize();
    		boolean Lighthor = false;
    		boolean LightVer = true;

    		gv.initGrid();
    		gv.buildHorLane(pm.getHorLanes());
    		gv.buildVerLane(pm.getVerLanes());

    		int trafficHorXPos = gv.setTrafficLightXPos(pm.getMiddleHor(),pm.getHorLanes());
    		int trafficHorYPos = gv.setTrafficLightYPos(pm.getMiddleVer(),pm.getVerLanes());
    		gv.buildTrafficLights(trafficHorXPos,trafficHorYPos, pm.getLightHor());

    		int trafficVerXPos = gv.setTrafficLightXPos(pm.getMiddleHor(),pm.getHorLanes());
			int trafficVerYPos = pm.getMiddleVer()-1;
			gv.buildTrafficLights(trafficVerXPos,trafficVerYPos, pm.getLightVer());

    		for(int i = 0; i > car.GenerateCarRandNum(); i++)
    		{
    			CarArray.add(new Car());
    		}

    		for(int i=0; i < car.GenerateCarRandNum(); i++)
    	{
    		CarArray.add(new Car());
    	}
    	for(int i =0; i < CarArray.size(); i++)
    	{
    	  int j=i;
    	  if(j==0)
    	  {
    	  	CarArray.get(i).setYPos(car.GenerateRandCarXPos(pm.getGridSize()));
    	  	CarArray.get(i).setXPos(car.GenerateRandCarYPos(pm.getHorLanes(),pm.getMiddleHor()));
    	  }
    	  else if (j==1)
    	  {
    	  	CarArray.get(i).setXPos(car.GenerateRandCarXPos(pm.getGridSize()));
    	  	CarArray.get(i).setYPos(car.GenerateRandCarYPos(pm.getVerLanes(),pm.getMiddleVer()));

    	  }
    	}
    	for (int i = 0; i< CarArray.size(); i++)
    	{
    		gv.buildCars(CarArray.get(i).getXPos(),CarArray.get(i).getYPos());
    	}

    		for(int i = 0; i<simCycles; i++)
    		{
    			if(i%3==0)
    			{
    				if(Lighthor == true)
    				{
    					Lighthor = false;
    					LightVer = true;
    				}
    				else
    				{
    					Lighthor = true;
    					LightVer = false;
    				}
    				pm.setLightHor(Lighthor);
    				pm.setLightVer(LightVer);
    				gv.buildTrafficLights(trafficHorXPos, trafficHorYPos, pm.getLightHor());
    				gv.buildTrafficLights(trafficVerXPos, trafficVerYPos, pm.getLightVer());

    			}
    			/**
     			* Animate cars
     			*/
    			for (int j = 0; j<CarArray.size(); j++)
    			{
    				int k =j;
    				if(k==0||j==0)
    				{
    					int X = CarArray.get(j).getXPos();
    					int Y = CarArray.get(j).getYPos();
    					if(Lighthor == false && Y == pm.getMiddleVer()-1)
    					{
    						gv.buildCars(CarArray.get(j).getXPos(),CarArray.get(j).getYPos());
    					}
    					else
    					{
    						gv.removeCars(X,Y);
    						Y++;

    						if(Y == gs)
    						{
    							Y--;
    							gv.removeCars(X,Y);
    						}
    						else
    						{
    							CarArray.get(j).setYPos(Y);
    							gv.buildCars(CarArray.get(j).getXPos(),CarArray.get(j).getYPos());
    						}
    					}
    			}
    				else if (k==1)
    					{
    						int X = CarArray.get(j).getXPos();
    						int Y = CarArray.get(j).getYPos();
    						if(LightVer == false && X == pm.getMiddleHor()-1)
    						{
    							gv.buildCars(CarArray.get(j).getXPos(), CarArray.get(j).getYPos());
    						}
    						else
    						{
    							gv.removeCars(X,Y);
    							X++;

    							if(X == gs)
    							{
    								X--;
    								gv.removeCars(X,Y);
    							}
    							else
    							{
    								CarArray.get(j).setXPos(X);
    								gv.buildCars(CarArray.get(j).getXPos(),CarArray.get(j).getYPos());
    							}
    						}


    					}
    				}
    				/**
     				* Slow frame rate
     				*/
    				gv.showGrid();
    				wait(500);
    				System.out.println(); //Spacers
         			System.out.println();
         			System.out.println();
    		}

    	}
    	else
    			{
    				System.out.println("Invalid number");
    			}
    			//break;
    }

    /**
     * The wait method to slow the cycle
     */
    public static void wait(int n)
    {

      long t0, t1;

      t0 = System.currentTimeMillis();

      do
      {
         t1 = System.currentTimeMillis();
      } while (t1 - t0 < n);
   }

   /**
     * Set Horizontal Proberbilty
     */

    public static float setHorProb()
    {
      String userChoice = GetUserInput.getUserChoice("Enter probability of car entering Horizontal lanes: ");
      int userChoiceInt = Integer.parseInt(userChoice);

      	return userChoiceInt;
   }

   /**
     * Set Vertical Proberbilty
     */

   public static float setVerProb()
   {
      String userChoice = GetUserInput.getUserChoice("Enter probability of car entering Vertical lanes: ");
      int userChoiceInt = Integer.parseInt(userChoice);

      	return userChoiceInt;
   }





}
